#include "conf_time.h"


//1.
long int get_time_from_device(){
    time_t rawtime;
    struct tm timeinfo;
    //get current time
    time(&rawtime);

    // if(!localtime_r(&rawtime, &timeinfo)) // 将结果存入用户提供的结构体
    // {
    //     fprintf(stderr, "localtime_r Switch time failed!\n");
    //     return -1;
    // }

    // strftime(buffer, buffer_size, "%Y-%m-%d %H:%M:%S", &timeinfo);
    printf("格式化时间: %ld\n", rawtime);
    return rawtime;
}

//2.
int set_time_to_device(){
    return 0;
}

//3.
int set_time_by_ntp(NetworkConfigNetworkNtpInfo *ntp_info){
    if(!ntp_info->server_addr || ntp_info->port <=0 ){
        fprintf(stderr, "ntp_server is null or ntp_port less than 0!\n");
        return -1;
    }

    char command[64];
    char output[1024];
    snprintf(command, sizeof(command), "ntpdate -u \"%s\"", ntp_info->server_addr);

    FILE *fp = popen(command, "r");
    if (!fp) {
        return -1;
    }

    size_t bytes_read = fread(output, 1, sizeof(output) - 1, fp);
    output[bytes_read] = '\0'; 

    int status = pclose(fp);
    if (status == -1) {
        return -1; 
    }

    printf("output:%s\n",output);
    return 0;
}
//4.
int set_time_by_manaual(const char* datetime){
    if(!datetime ){
        fprintf(stderr, "datetime  error!\n");
        return -1;
    }

    char command[64];
    char output[1024];
    snprintf(command, sizeof(command), "date -s \"@%s\"", datetime);

    printf("cmd:%s\n", command);
    FILE *fp = popen(command, "r");
    if (fp == NULL) {
        return -1; 
    }
    
    size_t bytes_read = fread(output, 1, sizeof(output) - 1, fp);
    output[bytes_read] = '\0'; 

    int status = pclose(fp);
    if (status == -1) {
        return -1; 
    }
    
    printf("output:%s\n",output);
    return 0;  // 成功
}

int save_time_info_to_ini(const NetworkConfigSystemTimeInfo *time_info)
{
    if ( !time_info) {
        return -1;
    }

    const char *section = "time_config";
    const char *keys[50];  // 足够大的数组来存储所有键
    const void *values[50];
    int types[50];
    int count = 0;
    int i;
    char key_buffer[50][64]; // 为动态生成的键名存储空间

    keys[count] = "time_zone";
    values[count] = time_info->time_zone;
    types[count] = VALUE_TYPE_STRING;
    count++;

    keys[count] = "time_format";
    values[count] = &time_info->time_format;
    types[count] = VALUE_TYPE_INTEGER;
    count++;

    keys[count] = "summer_time";
    values[count] = &time_info->summer_time;
    types[count] = VALUE_TYPE_INTEGER;
    count++;

    keys[count] = "timing_type";
    values[count] = &time_info->timing_type;
    types[count] = VALUE_TYPE_INTEGER;
    count++;

    printf("================================save count: %d\n", count);
    return write_config_to_ini(section, keys, values, types, count);
}

int load_time_info_from_ini(NetworkConfigSystemTimeInfo *time_info)
{
    if (!time_info) {
        return -1;
    }

    const char *section = "time_config";
    // 设置默认值
    NetworkConfigSystemTimeInfo default_time_info = {
        .time_zone = "1",
        .time_format = 1,
        .summer_time = 0,
        .timing_type = 0
    };

    // 复制默认值到输出参数
    memcpy(time_info, &default_time_info, sizeof(NetworkConfigSystemTimeInfo));

    const char *keys[50];
    void *values[50];
    int types[50];
    const void *defaults[50];
    int count = 0;
    int i;
    char key_buffer[50][64];

    keys[count] = "time_zone";
    values[count] = time_info->time_zone;
    types[count] = VALUE_TYPE_STRING;
    defaults[count] = &default_time_info.time_zone;
    count++;

    keys[count] = "time_format";
    values[count] = &time_info->time_format;
    types[count] = VALUE_TYPE_INTEGER;
    defaults[count] = &default_time_info.time_format;
    count++;

    keys[count] = "summer_time";
    values[count] = &time_info->summer_time;
    types[count] = VALUE_TYPE_INTEGER;
    defaults[count] = &default_time_info.summer_time;
    count++;

    keys[count] = "timing_type";
    values[count] = &time_info->timing_type;
    types[count] = VALUE_TYPE_INTEGER;
    defaults[count] = &default_time_info.timing_type;
    count++;

    printf("================================read count: %d\n", count);
    return read_config_from_ini(section, keys, values, types, defaults, count);
} 

int save_ntp_info_to_ini(const NetworkConfigNetworkNtpInfo *ntp_info)
{
    if ( !ntp_info) {
        return -1;
    }

    const char *section = "ntp_config";
    const char *keys[50];  // 足够大的数组来存储所有键
    const void *values[50];
    int types[50];
    int count = 0;
    int i;
    char key_buffer[50][64]; // 为动态生成的键名存储空间

    keys[count] = "server_addr";
    values[count] = ntp_info->server_addr;
    types[count] = VALUE_TYPE_STRING;
    count++;

    keys[count] = "ntp_port";
    values[count] = &ntp_info->port;
    types[count] = VALUE_TYPE_INTEGER;
    count++;

    keys[count] = "time_interval";
    values[count] = &ntp_info->interval;
    types[count] = VALUE_TYPE_INTEGER;
    count++;

    printf("================================save count: %d\n", count);
    return write_config_to_ini(section, keys, values, types, count);
}

int load_ntp_info_from_ini(NetworkConfigNetworkNtpInfo *ntp_info)
{
    if (!ntp_info) {
        return -1;
    }

    const char *section = "ntp_config";
    // 设置默认值
    NetworkConfigNetworkNtpInfo default_ntp_info = {
        .server_addr = "203.107.6.88",
        .port = 123,
        .interval = 1440
    };

    // 复制默认值到输出参数
    memcpy(ntp_info, &default_ntp_info, sizeof(NetworkConfigNetworkNtpInfo));

    const char *keys[50];
    void *values[50];
    int types[50];
    const void *defaults[50];
    int count = 0;
    int i;
    char key_buffer[50][64];

    keys[count] = "server_addr";
    values[count] = ntp_info->server_addr;
    types[count] = VALUE_TYPE_STRING;
    defaults[count] = &default_ntp_info.server_addr;
    count++;

    keys[count] = "ntp_port";
    values[count] = &ntp_info->port;
    types[count] = VALUE_TYPE_INTEGER;
    defaults[count] = &default_ntp_info.port;
    count++;

    keys[count] = "time_interval";
    values[count] = &ntp_info->interval;
    types[count] = VALUE_TYPE_INTEGER;
    defaults[count] = &default_ntp_info.interval;
    count++;

    printf("================================read count: %d\n", count);
    return read_config_from_ini(section, keys, values, types, defaults, count);
} 


static TimeZoneEntry_S timezone_table[] = {
    {1, "Etc/GMT+12", "GMT-12:00"},    // GMT-12
    {2, "Etc/GMT+11", "GMT-11:00"},      // GMT-11
    {3, "Etc/GMT+10", "GMT-10:00"},    // GMT-10
    {4, "Etc/GMT+9", "GMT-09:00"},   // GMT-9
    {5, "Etc/GMT+8", "GMT-08:00"}, // GMT-8
    {6, "Etc/GMT+7", "GMT-07:00"}, // GMT-7
    {7, "Etc/GMT+6", "GMT-06:00"},     // GMT-6
    {8, "Etc/GMT+5", "GMT-05:00"},    // GMT-5
    {9, "Etc/GMT+4", "GMT-04:00"},     // GMT-4
    {10, "Etc/GMT+3", "GMT-03:00"},    // GMT-3
    {11, "Etc/GMT+2", "GMT-02:00"},   // GMT-2
    {12, "Etc/GMT+1", "GMT-01:00"},     // GMT-1
    {13, "Etc/GMT", "GMT+00:00"},     // GMT+0
    {14, "Etc/GMT-1", "GMT+01:00"},    // GMT+1
    {15, "Etc/GMT-2", "GMT+02:00"},       // GMT+2
    {16, "Etc/GMT-3", "GMT+03:00"},       // GMT+3
    {17, "Asia/Tehran", "GMT+03:30"},         // GMT+3:30
    {18, "Etc/GMT-4", "GMT+04:00"},          // GMT+4
    {19, "Asia/Kabul", "GMT+04:30"},          // GMT+4:30
    {20, "Etc/GMT-5", "GMT+05:00"},        // GMT+5
    {21, "Asia/Kolkata", "GMT+05:30"},        // GMT+5:30
    {22, "Asia/Kathmandu", "GMT+05:45"},      // GMT+5:45
    {23, "Etc/GMT-6", "GMT+06:00"},         // GMT+6
    {24, "Asia/Yangon", "GMT+06:30"},         // GMT+6:30
    {25, "Etc/GMT-7", "GMT+07:00"},        // GMT+7
    {26, "Etc/GMT-8", "GMT+08:00"},       // GMT+8
    {27, "Etc/GMT-9", "GMT+09:00"},          // GMT+9
    {28, "Australia/Darwin", "GMT+09:30"},  // GMT+9:30
    {29, "Etc/GMT-10", "GMT+10:00"},    // GMT+10
    {30, "Etc/GMT-11", "GMT+11:00"},        // GMT+11
    {31, "Etc/GMT-12", "GMT+12:00"},    // GMT+12
    {32, "Etc/GMT-13", "GMT+13:00"},   // GMT+13 
};

static void extract_gmt_info(const char* gmt_str, char* sign, int* hours, int* minutes) {
    // 查找GMT后面的符号和数字
    const char* ptr = strstr(gmt_str, "GMT");
    if (ptr == NULL) {
        *sign = '\0';
        *hours = 0;
        *minutes = 0;
        return;
    }
    
    ptr += 3; // 跳过"GMT"
    
    // 提取符号
    *sign = *ptr;
    if (*sign != '+' && *sign != '-') {
        *sign = '+'; // 默认正号
    } else {
        ptr++; // 跳过符号
    }
    
    // 提取小时和分钟
    if (sscanf(ptr, "%d:%d", hours, minutes) != 2) {
        // 如果没有分钟部分
        *minutes = 0;
        sscanf(ptr, "%d", hours);
    }
}

int set_timezone_by_value(const char *timezone) {


    char zone_path[256];
    const char* tz_name = NULL;
    int timezone_value= 0;
    struct stat st;
    char sign = '\0';
    int hours = 0;
    int minutes = 0;

    // 查找时区名称
    for (size_t i = 0; i < sizeof(timezone_table)/sizeof(TimeZoneEntry_S); i++) {
        if (memcmp(timezone, timezone_table[i].gmt, strlen(timezone_table[i].gmt)) == 0) {
            tz_name = timezone_table[i].tz_name;
            break;
        }
    }

    printf("timezone_value:%d,tz_name:%s;",timezone_value, tz_name);
    if (!tz_name) {
        fprintf(stderr, "Invalid timezone value: %d\n", timezone_value);
        return -1;
    }

    // 构造时区文件路径
    snprintf(zone_path, sizeof(zone_path), "%s/%s", ZONEINFO_DIR, tz_name);

    // 验证时区文件存在
    if (access(zone_path, F_OK) != 0) {
        fprintf(stderr, "Timezone file not found: %s\n", zone_path);
        return -1;
    }

    // 删除旧的localtime链接
    if (unlink(LOCALTIME_PATH) != 0 && errno != ENOENT) {
        perror("Failed to remove old localtime");
        return -1;
    }

    // 创建新的符号链接
    if (symlink(zone_path, LOCALTIME_PATH) != 0) {
        perror("Failed to create symlink");
        return -1;
    }

    // 更新/etc/timezone文件
    FILE* fp = fopen(TIMEZONE_FILE, "w");
    if (!fp) {
        perror("Failed to update timezone file");
        return -1;
    }
    fprintf(fp, "%s\n", tz_name);
    fclose(fp);

    return 0;
}